/*
   This file is part of the 'Let's Do Stuff Together' project
   http://code.google.com/p/dostufftogether/

   Copyright 2010 Christoph Fuchs, Stefan Thaler

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package location;

import static java.lang.Math.PI;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.sqrt;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;


/**
 * Class for Earth centered, Earh fixed cartesian coordinates.
 * {@link http://www.mathworks.com/access/helpdesk/help/toolbox/aeroblks/llatoecefposition.html}
 * {@link http://de.wikipedia.org/wiki/World_Geodetic_System_1984}
 * {@link http://en.wikipedia.org/wiki/Geodetic_system}
 * WGS 84 ellipsoid
 * @author Stefan
 * TODO TEST!!!!!!!
 */
public class ECEFCoordinates {
	
	public static final Double f = 1/298.257223563d;
	public static final Double a =6378137.0; //semi-major ellipis axis
	public static final Double b = a * (1.0 -f ); //semai minor axis
	
	public static final Double eSquare = 2*f -f*f;
	public static final Double e2Square = f*(2-f)/((1-f)*(1-f));
	
	
	@Getter(AccessLevel.PUBLIC)
	@Setter(AccessLevel.PROTECTED)
	private Double x; 
	
	@Getter(AccessLevel.PUBLIC)
	@Setter(AccessLevel.PROTECTED)
	private Double y; 
	
	@Getter(AccessLevel.PUBLIC)
	@Setter(AccessLevel.PROTECTED)
	private Double z; 
	/**
	 * creates new ECEF coordinates from LLA. returns x,y,z in ECEF in KM from earth center.
	 * @param latitude
	 * @param longitude
	 * @param altitude in meters
	 */
	public ECEFCoordinates (Double latitude, Double longitude, Double altitude) {
		//convert to radion
		latitude = latitude*PI /180.0;
		longitude = longitude*PI /180.0;
		
		Double H = sqrt(1-e2Square*sin(latitude)*sin(latitude));
		Double aHplusH = a/H+altitude;
		
		setX( aHplusH * cos(latitude)*cos(longitude)  );
		setY( aHplusH * cos(latitude)*sin(longitude) );
		setZ(((a*(1-e2Square))/H+altitude)*sin(latitude) );
	}
	
	public ECEFCoordinates (String latitude, String longitude, String altitude) {
		this (Double.parseDouble(latitude),Double.parseDouble(longitude),Double.parseDouble(altitude));
	}
}
